local name, DB = ...

DB.Class = function (proto)
    local prototype = {}
    for k, v in pairs(proto) do
        if k ~= "constructor" then
            prototype[k] = v
        end
    end
    local metatable = {}
    metatable.__index = prototype

    return setmetatable({
        constructor = proto.constructor,
        metatable = metatable,
        prototype = prototype,
    }, {
        __call = function (self, ...)
            local object = setmetatable({}, self.metatable)
            if self.constructor then
                self.constructor(object, ...)
            end
            return object
        end,
        __index = {
            is_a = function (self, v)
                if type(v) ~= "table" then return end
                return getmetatable(v) == self.metatable
            end,
        },
    })
end

DB.Frame = function (proto)
    local prototype = {}
    for k, v in pairs(proto) do
        if k ~= "constructor" then
            prototype[k] = v
        end
    end
    local metatable = {}
    metatable.__index = prototype

    return setmetatable({
        constructor = proto.constructor,
        metatable = metatable,
        prototype = prototype,
    }, {
        __call = function (self, ...)
			local parent = self.prototype.parent or (...)
            local object = CreateFrame(self.prototype.class, nil, parent)
			if not getmetatable(self.prototype) then
				setmetatable(self.prototype, getmetatable(object))
			end
			setmetatable(object, self.metatable)
            if self.constructor then
                self.constructor(object, ...)
            end
            return object
        end,
    })
end
